<?php
/**
 * 生成微信公众号二维码处理各种绑定事件
 *
 * Author: Zeon
 * Date: 2017/12/28
 * Created by Panxsoft.
 */

namespace App\Models\OpenWechat;

use App\Models\Customer\DeviceAccount;
use App\Models\Panx\Visit;
use App\Models\Store\Store;
use App\Services\OpenWechat\TemplateNotice;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;

/**
 * @property int id
 * @property string value - 扫码事件保存的临时数据值
 * @property array data - 扫码事件保存的复杂数据值
 * @property string type - 类型常量
 * @property int scan_count - 扫码次数
 *
 * @mixin Builder
 */
class ScanEvent extends Model
{
    const PREFIX = 'MIR_'; // 本项目微信扫码场景值前缀
    const SEPARATOR = ':';  // 本项目微信扫码场景值与表ID的分隔符

    const TYPE_PAD_USER_LOGIN = 'PAD_USER_LOGIN';      // 用户登录
    const TYPE_STORE_STAFF_BIND = 'STORE_STAFF_BIND';  // 后台店铺员工绑定
    const TYPE_APP_STORE_STAFF_BIND = 'STORE_APP_STAFF_BIND';  // APP 绑定店员
    const TYPE_PAD_USER_IMAGE = 'PAD_USER_IMAGE';      // 用户收藏试妆照片
    const TYPE_REPLY_IMAGE = 'REPLY_IMAGE'; // 分享图片
    const TYPE_REPLY_VIDEO = 'REPLY_VIDEO'; // 分享视频
    const TYPE_BOOM_GAME = 'BOOM_GAME'; // 扫码手机玩消消乐
    const TYPE_COUPON_CARD = 'COUPON_CARD'; // 抽奖完成扫码领奖

    const NO_SCAN_COUNT = 0;  // 没有扫码
    const IS_SCAN_COUNT = 1;  // 已经扫码

    protected $table = 'scan_events';

    protected static $unguarded = true;

    protected $casts = [
        'scan_count' => 'int',
        'data'       => 'json'
    ];

    const DATA_TEMPLATE_NOTICE_SENT = 'tpl_notice_sent'; // 模板消息是否已发送
    const DATA_TEMPLATE_NOTICE_RES = 'tpl_notice_res'; // 发送模板消息返回数据

    /**
     * 生成临时二维码场景值，用于扫码回调查找 ScanEvent
     *
     * @example => 'MIR_PAD_USR_LOGIN:1'
     */
    public function getSceneValue(): string
    {
        return self::PREFIX . $this->type . self::SEPARATOR . $this->id;
    }

    /**
     * @param $type
     * @param string|int $value
     * @param array $data
     * @return ScanEvent
     */
    public static function createNewEvent(string $type,
                                          $value = null,
                                          array $data = null): self
    {
        return (new self)->create(compact('type', 'value', 'data'));
    }

    public function isScanned(): bool
    {
        return $this->scan_count > 0;
    }

    public function getPadLoginServeStaffId(): ?int
    {
        $id = $this->data['store_admin_id'] ?? null;

        if (! $id) {
            return null;
        } else {
            return (int) $id;
        }
    }

    /**
     * 扫码成功更新微信用户到店访问
     */
    public function incrementWechatUserVisitStore(): bool
    {
        if ($this->type !== self::TYPE_PAD_USER_LOGIN
            || !isset($this->data['store_id'])
        ) {
            return false;
        }

        $store_id = $this->data['store_id'];

        Store::incrementVisitById($store_id);

        Visit::createWechatUserVisitStore((int)$this->value, (int)$store_id);

        return true;
    }

    public function isPadUserLogin()
    {
        return $this->type === self::TYPE_PAD_USER_LOGIN;
    }

    public function appLogin(int $wechat_user_id): bool
    {
        return $this->update([
            'value'      => $wechat_user_id,
            'scan_count' => $this->scan_count + 1,
        ]);
    }

    public function isTemplateNoticeSent(): bool
    {
        return isset($this->data[self::DATA_TEMPLATE_NOTICE_SENT])
            ? ((bool)$this->data[self::DATA_TEMPLATE_NOTICE_SENT])
            : false;
    }

    /**
     * @see TemplateNotice::send() - $notice_res 的格式参考 return
     *
     * @param array|null $notice_res
     *
     * @return bool
     */
    public function updateDataTemplateSentResponse(array $notice_res = null): bool
    {
        $data = $this->data ?? [];

        if ($notice_res) {
            $data[self::DATA_TEMPLATE_NOTICE_SENT] = true;
            $data[self::DATA_TEMPLATE_NOTICE_RES] = $notice_res;
        } else {
            $data[self::DATA_TEMPLATE_NOTICE_SENT] = false;
        }

        return $this->update(compact('data'));
    }

    /**
     * 生成微信用户登录 App 微信二维码
     *
     * @param Store $store
     * @param DeviceAccount $deviceAccount
     * @param int|null $store_admin_id
     *
     * @return ScanEvent
     */
    public static function createAppLoginEvent(Store $store,
                                               DeviceAccount $deviceAccount,
                                               int $store_admin_id = null): self
    {
        return self::createNewEvent(
            self::TYPE_PAD_USER_LOGIN,
            'WECHAT_USER_ID_PLACEHOLDER',
            [
                'store_admin_id' => $store_admin_id,
                'store_id'       => $store->id,
                'language'       => $deviceAccount->language,
                'customer_id'    => $store->customer_id,       // 无公众号的客户customer_id
            ]
        );
    }

    /**
     * @param int $customer_id
     *
     * @return ScanEvent
     */
    public static function createBoomGameEvent(int $customer_id): self
    {
        return self::createNewEvent(
            self::TYPE_BOOM_GAME,
            'WECHAT_USER_ID_PLACEHOLDER',
            [
                'customer_id'    => $customer_id,
            ]
        );
    }

    /**
     * @param int $customer_id
     *
     * @param int $coupon_ticket_id
     *
     * @return ScanEvent
     */
    public static function createCouponCartEvent(int $customer_id, int $coupon_ticket_id): self
    {
        return self::createNewEvent(
            self::TYPE_COUPON_CARD,
            'WECHAT_USER_ID_PLACEHOLDER',
            compact('customer_id', 'coupon_ticket_id')
        );
    }
}
